#!/bin/bash

# ===============================================
# Docker Redis Stack 运维脚本
# 文件名 redis-ops.sh 
# 版本: v1.3
# 创建时间: $(date +%Y-%m-%d)
# 更新说明: 同步部署脚本v1.8版本，保持版本一致性
# 功能: Redis Stack服务运维管理
# ===============================================

# 脚本配置参数
REDIS_CONTAINER_NAME="redis-stack"
REDIS_PASSWORD="Hlj@20220715"
REDIS_PORT="6379"

# 目录配置
BASE_DIR="/docker/redis-stack"
DATA_DIR="$BASE_DIR/data"
LOG_DIR="$BASE_DIR/logs"
CONF_DIR="$BASE_DIR/conf"

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 日志函数
log_info() {
    echo -e "${BLUE}[INFO]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"
}

# 检查Docker服务状态
check_docker_service() {
    if ! command -v docker &> /dev/null; then
        log_error "Docker未安装"
        return 1
    fi
    
    if ! systemctl is-active --quiet docker; then
        log_error "Docker服务未运行"
        return 1
    fi
    
    return 0
}

# 检查Redis容器是否存在
check_redis_container() {
    if ! docker ps -a --filter "name=$REDIS_CONTAINER_NAME" --format "{{.Names}}" | grep -q .; then
        log_error "Redis容器不存在: $REDIS_CONTAINER_NAME"
        return 1
    fi
    return 0
}

# 启动Redis服务
start_redis() {
    log_info "启动Redis服务..."
    
    if ! check_docker_service; then
        return 1
    fi
    
    # 检查容器是否存在
    if ! check_redis_container; then
        log_error "请先使用部署脚本创建Redis容器"
        return 1
    fi
    
    # 检查容器是否已在运行
    if docker ps --filter "name=$REDIS_CONTAINER_NAME" --filter "status=running" --format "{{.Names}}" | grep -q .; then
        log_warn "Redis服务已在运行"
        return 0
    fi
    
    # 启动容器
    if docker start $REDIS_CONTAINER_NAME; then
        # 等待服务启动
        sleep 5
        
        # 验证服务状态
        if docker ps --filter "name=$REDIS_CONTAINER_NAME" --filter "status=running" --format "{{.Names}}" | grep -q .; then
            log_success "Redis服务启动成功"
            return 0
        else
            log_error "Redis服务启动后异常停止"
            docker logs $REDIS_CONTAINER_NAME --tail 10
            return 1
        fi
    else
        log_error "Redis服务启动失败"
        return 1
    fi
}

# 停止Redis服务
stop_redis() {
    log_info "停止Redis服务..."
    
    if ! check_docker_service; then
        return 1
    fi
    
    # 检查容器是否存在
    if ! check_redis_container; then
        log_error "Redis容器不存在"
        return 1
    fi
    
    # 检查容器是否在运行
    if ! docker ps --filter "name=$REDIS_CONTAINER_NAME" --filter "status=running" --format "{{.Names}}" | grep -q .; then
        log_warn "Redis服务未在运行"
        return 0
    fi
    
    # 停止容器
    if docker stop $REDIS_CONTAINER_NAME; then
        # 等待服务停止
        sleep 3
        
        # 验证服务状态
        if ! docker ps --filter "name=$REDIS_CONTAINER_NAME" --filter "status=running" --format "{{.Names}}" | grep -q .; then
            log_success "Redis服务停止成功"
            return 0
        else
            log_error "Redis服务停止失败"
            return 1
        fi
    else
        log_error "Redis服务停止失败"
        return 1
    fi
}

# 重启Redis服务
restart_redis() {
    log_info "重启Redis服务..."
    
    if ! check_docker_service; then
        return 1
    fi
    
    # 先停止服务
    if stop_redis; then
        # 等待一下再启动
        sleep 2
        
        # 启动服务
        if start_redis; then
            log_success "Redis服务重启成功"
            return 0
        else
            log_error "Redis服务重启失败（启动阶段）"
            return 1
        fi
    else
        log_error "Redis服务重启失败（停止阶段）"
        return 1
    fi
}

# 查看Redis服务状态
status_redis() {
    log_info "查看Redis服务状态..."
    
    if ! check_docker_service; then
        return 1
    fi
    
    echo ""
    echo "=== Redis服务状态信息 ==="
    echo ""
    
    # 显示容器基本信息
    echo "容器信息:"
    docker ps -a --filter "name=$REDIS_CONTAINER_NAME" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}\t{{.Image}}"
    echo ""
    
    # 检查容器是否存在
    if ! check_redis_container; then
        log_error "Redis容器不存在"
        return 1
    fi
    
    # 检查运行状态
    if docker ps --filter "name=$REDIS_CONTAINER_NAME" --filter "status=running" --format "{{.Names}}" | grep -q .; then
        log_success "Redis服务正在运行"
        
        # 显示资源使用情况
        echo "资源使用情况:"
        docker stats $REDIS_CONTAINER_NAME --no-stream --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}"
        echo ""
        
        # 测试服务连接
        echo "服务连接测试:"
        if docker exec $REDIS_CONTAINER_NAME redis-cli -a "$REDIS_PASSWORD" ping | grep -q "PONG"; then
            echo "  ✅ Redis服务连接正常"
        else
            echo "  ❌ Redis服务连接失败"
        fi
        
        # 显示基本信息
        echo ""
        echo "Redis基本信息:"
        docker exec $REDIS_CONTAINER_NAME redis-cli -a "$REDIS_PASSWORD" info server | grep -E "(redis_version|redis_mode|os|process_id)"
        
    else
        log_warn "Redis服务未运行"
    fi
    
    echo ""
    return 0
}

# 查看Redis服务日志
logs_redis() {
    local follow=""
    local lines=50
    
    # 解析参数
    while [[ $# -gt 0 ]]; do
        case $1 in
            -f|--follow)
                follow="-f"
                shift
                ;;
            -n|--lines)
                lines="$2"
                shift 2
                ;;
            *)
                log_error "未知参数: $1"
                return 1
                ;;
        esac
    done
    
    log_info "查看Redis服务日志..."
    
    if ! check_docker_service; then
        return 1
    fi
    
    if ! check_redis_container; then
        log_error "Redis容器不存在"
        return 1
    fi
    
    echo ""
    echo "=== Redis服务日志（最近 ${lines} 行）==="
    echo ""
    
    if [ -n "$follow" ]; then
        log_info "进入实时日志模式，按 Ctrl+C 退出"
        docker logs $REDIS_CONTAINER_NAME $follow --tail $lines
    else
        docker logs $REDIS_CONTAINER_NAME --tail $lines
    fi
    
    return 0
}

# 进入Redis CLI
cli_redis() {
    log_info "进入Redis CLI..."
    
    if ! check_docker_service; then
        return 1
    fi
    
    if ! check_redis_container; then
        log_error "Redis容器不存在"
        return 1
    fi
    
    # 检查服务是否运行
    if ! docker ps --filter "name=$REDIS_CONTAINER_NAME" --filter "status=running" --format "{{.Names}}" | grep -q .; then
        log_error "Redis服务未运行，请先启动服务"
        return 1
    fi
    
    echo ""
    echo "=== 进入Redis CLI ==="
    echo "提示: 输入 'exit' 或按 Ctrl+D 退出"
    echo ""
    
    docker exec -it $REDIS_CONTAINER_NAME redis-cli -a "$REDIS_PASSWORD"
    
    return 0
}

# 备份Redis数据
backup_redis() {
    local backup_dir="$BASE_DIR/backup"
    local timestamp=$(date +%Y%m%d_%H%M%S)
    local backup_file="redis_backup_${timestamp}.rdb"
    
    log_info "备份Redis数据..."
    
    if ! check_docker_service; then
        return 1
    fi
    
    if ! check_redis_container; then
        log_error "Redis容器不存在"
        return 1
    fi
    
    # 检查服务是否运行
    if ! docker ps --filter "name=$REDIS_CONTAINER_NAME" --filter "status=running" --format "{{.Names}}" | grep -q .; then
        log_error "Redis服务未运行，无法备份"
        return 1
    fi
    
    # 创建备份目录
    mkdir -p "$backup_dir"
    
    # 执行备份
    log_info "执行Redis数据备份..."
    
    # 使用BGSAVE命令进行后台备份
    if docker exec $REDIS_CONTAINER_NAME redis-cli -a "$REDIS_PASSWORD" bgsave | grep -q "Background saving started"; then
        log_info "后台备份已启动，等待完成..."
        
        # 等待备份完成
        local max_wait=30
        local wait_count=0
        
        while [ $wait_count -lt $max_wait ]; do
            if docker exec $REDIS_CONTAINER_NAME redis-cli -a "$REDIS_PASSWORD" info persistence | grep -q "rdb_bgsave_in_progress:0"; then
                break
            fi
            sleep 1
            ((wait_count++))
        done
        
        if [ $wait_count -eq $max_wait ]; then
            log_warn "备份超时，但可能仍在进行中"
        fi
        
        # 复制备份文件
        if docker cp "$REDIS_CONTAINER_NAME:/data/dump.rdb" "$backup_dir/$backup_file"; then
            log_success "Redis数据备份完成: $backup_dir/$backup_file"
            
            # 显示备份文件信息
            echo "备份文件信息:"
            ls -la "$backup_dir/$backup_file"
            return 0
        else
            log_error "备份文件复制失败"
            return 1
        fi
    else
        log_error "备份命令执行失败"
        return 1
    fi
}

# 显示帮助信息
show_help() {
    echo ""
    echo "==============================================="
    echo "    Docker Redis Stack 运维脚本 v1.2"
    echo "==============================================="
    echo ""
    echo "使用说明:"
    echo "  ./redis-ops.sh <命令> [选项]"
    echo ""
    echo "可用命令:"
    echo "  start                   启动Redis服务"
    echo "  stop                    停止Redis服务"
    echo "  restart                 重启Redis服务"
    echo "  status                  查看Redis服务状态"
    echo "  logs [选项]             查看Redis服务日志"
    echo "  cli                     进入Redis CLI"
    echo "  backup                  备份Redis数据"
    echo "  help                    显示此帮助信息"
    echo ""
    echo "日志查看选项:"
    echo "  -f, --follow            实时跟踪日志"
    echo "  -n, --lines <行数>      显示指定行数的日志（默认: 50）"
    echo ""
    echo "示例:"
    echo "  ./redis-ops.sh start              # 启动服务"
    echo "  ./redis-ops.sh status             # 查看状态"
    echo "  ./redis-ops.sh logs -f             # 实时查看日志"
    echo "  ./redis-ops.sh logs -n 100        # 查看最近100行日志"
    echo "  ./redis-ops.sh cli                 # 进入Redis CLI"
    echo "  ./redis-ops.sh backup             # 备份数据"
    echo ""
}

# 主函数
main() {
    local command="$1"
    
    case "$command" in
        start)
            shift
            start_redis "$@"
            ;;
        stop)
            shift
            stop_redis "$@"
            ;;
        restart)
            shift
            restart_redis "$@"
            ;;
        status)
            shift
            status_redis "$@"
            ;;
        logs)
            shift
            logs_redis "$@"
            ;;
        cli)
            shift
            cli_redis "$@"
            ;;
        backup)
            shift
            backup_redis "$@"
            ;;
        help|--help|-h)
            show_help
            ;;
        *)
            if [ -z "$command" ]; then
                show_help
            else
                log_error "未知命令: $command"
                echo ""
                echo "使用 './redis-ops.sh help' 查看可用命令"
                return 1
            fi
            ;;
    esac
}

# 脚本执行入口
if [ "$1" = "--version" ] || [ "$1" = "-v" ]; then
    echo "Docker Redis Stack 运维脚本 v1.2"
    exit 0
fi

# 执行主函数
main "$@"